package com.easytouch.core.task;

import android.content.Context;
import android.os.SystemClock;
import android.util.Pair;

import com.easytouch.core.Configure;
import com.easytouch.core.DriverThread;
import com.easytouch.core.encryption.ETEncrypt;
import com.easytouch.core.model.GoodsModel;
import com.easytouch.core.utils.Log;
import com.easytouch.core.utils.OrderGenerator;
import com.easytouch.core.utils.Tools;

import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Crea gulin on 2017/8/18.
 */

public class MobilePayTask extends Task {

    private Log mLogger = new Log("MobilePayTask.txt");
    private GoodsModel mGoods = null;
    private String orderID;

    private int payState;// 0：未扫码 1：已扫码 2：已付款
    private String payType;// 1：微信 2：百付宝 3：支付宝
    private int step = 0;

    private String mIp;
    private int mPort = 6001;

    private int mPrice = 0; //打折后的价格

    private int mAmount = 1;

    private Context mContext;

    //key=订单号    value=[机器价格，实际支付价格]
    public static Map<String, int[]> priceMap = new HashMap<>();


    public MobilePayTask(final String pOrderNo, final GoodsModel pGoods) {
        this(pOrderNo, pGoods, 1);
    }

    public MobilePayTask(final String pOrderNo, final GoodsModel pGoods, final int pAmount) {
        super(pOrderNo);
        String order = pOrderNo;
        String[] split = pOrderNo.split("-");
        if (split != null) {
            order = split[0];
        }
        mGoods = pGoods;
        orderID = order;
        mLogger.i("orderId:" + orderID);
        mPrice = mGoods.getPrice();
        mLogger.i("mPrice:" + mPrice + ",orderId:" + orderID);
        mAmount = pAmount;

        mIp = Configure.getConfigData(Configure.CONFIG_PAY_IP);
        try {
            mPort = Integer.parseInt(Configure.getConfigData(Configure.CONFIG_PAY_PORT));
        } catch (NumberFormatException e) {
        }
        mLogger.i("mIp:" + mIp + ",mPort:" + mPort);
    }

    @Override
    public void run() {
        Socket socket = null;
        InputStream in = null;
        OutputStream out = null;
        InetSocketAddress address = null;
        boolean isOutGoodsSucc = false;
        String payMethod = "";
        int retry = 3; //重试连接三次
        boolean isConnectOk = false;
        while (!isConnectOk) {
            try {
                isConnectOk = true;
                socket = new Socket();
                socket.setSoTimeout(30000);
                address = new InetSocketAddress(mIp, mPort);
                socket.connect(address, 15000);
                socket.setKeepAlive(true);
            } catch (IOException e) {
                retry--;
                isConnectOk = false;
                if (retry <= 0) {
                    //重试连接失败
                    mLogger.i("与后台服务器连接重试失败，cause is : " + e.getMessage());
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                    cleanup(-1, "net error");
                    return;
                }
            }
        }

        try {
//          boolean isScan = false;
            int state = 0;
            in = socket.getInputStream();
            out = socket.getOutputStream();
            byte[] buffer = new byte[26];
            byte[] lenBuffer = new byte[3];
            for (int i = 0; i < 80; i++) { // 90循环40次，每次间隔1.5秒询问后台支付状态
                try {
                    if (state == 0) {
                        // 协议30+3位长度+(2位请求状态+订单号)加密
                        String message = encrypt("01", orderID);
                        mLogger.i("send:" + message + "   orderID:" + orderID);
                        out.write(message.getBytes());
                        out.flush();
                        // 数据格式：22位订单号 + 1(0：未扫码 1：已扫码 2：已付款) + 1(1：微信 2：百付宝 3：支付宝)
                        in.read(lenBuffer);
                        String lenStr = new String(lenBuffer);
                        int len = 0;
                        try {
                            len = Integer.parseInt(lenStr);
                        } catch (NumberFormatException e) {

                        }
                        if (len <= 1) {
                            throw new IOException("buffer length errror");
                        }
                        if (len > 999)
                            len = 999;
                        buffer = new byte[len];
                        in.read(buffer);
                    }
                    if (state > 0 || !isEmpty(buffer)) { // byte数组不为空，表示已获取到数据
                        if (state == 0) {
                            String result = new String(buffer);
                            result = ETEncrypt.decode(result);
                            mLogger.i("buffer = " + result);
                            payState = Integer.parseInt(result.substring(22, 23));
                            mLogger.i("payState = " + payState);
                            payType = result.substring(23, 24);
                            mLogger.i("payType = " + payType);
                            if ("1".equals(payType)) {
                                mLogger.i("微信支付");
                                payMethod = DriverThread.OUT_GOODS_WEIXINPAY;
//                                double discount = (double) mGoods.getDiscount() / 100.0;
//                                mPrice = (int) ((double) mPrice * discount);
//                                if (mPrice < 1)
//                                    mPrice = 1; // 最小1分钱
                            } else if ("2".equals(payType)) {
                                mLogger.i("百付宝支付");
                                payMethod = DriverThread.OUT_GOODS_BAIPAY;
                            } else if ("3".equals(payType) || "4".equals(payType)) {
                                payMethod = DriverThread.OUT_GOODS_ALIPAY;
                                double discount = (double) mGoods.getDiscount() / 100.0;
                                mPrice = (int) ((double) mPrice * discount);
                                mLogger.i("支付宝 价格：" + mPrice + "  打折：" + discount);
                                if (mPrice < 1)
                                    mPrice = 1; // 最小1分钱
                            } else if ("5".equals(payType)) {
                                mLogger.i("翼支付");
                                payMethod = DriverThread.OUT_GOODS_BESTPAY;
                            } else if ("6".equals(payType)) {
                                mLogger.i("银联二维码支付");
                                payMethod = DriverThread.OUT_GOODS_UNIONPAY_QR;
                            } else if ("a".equals(payType)) {
                                mLogger.i("全民付支付");
                                payMethod = DriverThread.OUT_GOODS_UNIONPAY_QR;
                                double discount = (double) mGoods.getDiscount() / 100.0;
                                mPrice = (int) ((double) mPrice * discount);
                                mLogger.i("全民付 价格:" + mPrice + "  打折：" + discount);
                                if (mPrice < 1)
                                    mPrice = 1; // 最小1分钱
                            } else if ("b".equals(payType)) {
                                payMethod = DriverThread.OUT_GOODS_CLOUE_QR;
                                double discount = (double) mGoods.getDiscount() / 100.0;
                                mPrice = (int) ((double) mPrice * discount);
                                mLogger.i("云码价格：" + mPrice + "  打折：" + discount);
                                if (mPrice < 1)
                                    mPrice = 1; // 最小1分钱
                            } else {
                                mLogger.i("无");
//                                payMethod = DriverThread.OUT_GOODS_WEIXINPAY;
                            }

//                            if(!isScan && payState == 1) //已扫码
//                            {
//                                isScan = true;
//                                //发送已扫码的广播
//                                Intent intent = new Intent(GoodsDetailActivity2.NOTICE_SHOW_QR_TRADE_RESULT);
//                                intent.putExtra(GoodsDetailActivity2.OUT_GOODS_RESULT, GoodsDetailActivity2.QR_SCAN);
//                                AlipayService.this.sendBroadcast(intent);
//                            }
                        }
                        if (state > 0 || payState == 2) { // 已付款
                            if (state == 0 || state == 1) {
                                state = 1;
                                out.write(encrypt("06", orderID).getBytes());
                                out.flush();
                                state = 2;
                            }
                            if (state == 2) {
//                                  已支付，发送广播通知页面
                                mLogger.i("pay success");
                                for (int j = 0; j < mAmount; j++) { //多次出货
                                    SystemClock.sleep(600);
//                                    SimpleDateFormat sd = new SimpleDateFormat("HHmmss", Locale.US);
//                                    String tradeTrace = sd.format(new Date());
                                    String tradeTrace = OrderGenerator.getNextTrace();
                                    if (mGoods.getDiscount() != 100) {
                                        int goodsPriceOri = mGoods.getPrice();
                                        int goodsPrice = goodsPriceOri * mGoods.getDiscount() / 100;
                                        if (goodsPrice < 1) {
                                            goodsPrice = 1; //最低1分钱
                                        }
                                        mPrice = goodsPrice;
                                        mLogger.i("price: " + mPrice);
                                    }
                                    int payPrice = getPayPrice(orderID);
                                    priceMap.put(orderID.trim(), new int[]{mPrice, payPrice});
                                    mLogger.i("key:" + orderID + "长度:" + orderID.length() + "   value:" + Arrays.toString(priceMap.get(orderID)));
                                    mLogger.i("price1   " + mPrice);
                                    //出货
                                    mLogger.i("出货信息box:" + mGoods.getBox() + ",column:" + mGoods.getColumn() + ",mPrice:" + mPrice + ",payMethod:" + payMethod + ",orderID:" + orderID);
                                    if (!DriverThread.getInstance().outGoods(mGoods.getBox(), mGoods.getColumn(), mPrice, payMethod, tradeTrace, orderID)) {
                                        //出货失败，发送失败广播
                                        sendResult(-1, tradeTrace, null);
                                        cleanup(0, "finish");
                                        return;
                                    }
                                    mLogger.i("trace:" + tradeTrace + " orderId:" + orderID);
                                    step = 0;
                                    int result = -1;
                                    try {
                                        while (step <= 120) {
                                            Thread.sleep(500);
                                            step++;
                                            Pair<Integer, Integer> pair = DriverThread.getInstance().getResult(tradeTrace);
                                            if (pair != null) {
                                                result = pair.first;
                                                break;
                                            }
                                        }
                                    } catch (InterruptedException e) {
                                    }

                                    if (result == 0) { // 出货成功
                                        isOutGoodsSucc = true;
                                    } else { // 出货失败
                                        isOutGoodsSucc = false;
                                    }
                                    mLogger.i("isOutGoodsSucc = " + isOutGoodsSucc);
                                    //出货结果,发送广播
                                    sendResult(result, tradeTrace, payMethod);

                                    if (isOutGoodsSucc) { // 出货成功
                                        state = 3;
                                        out.write(encrypt("00", orderID).getBytes());
                                        out.flush();

                                        //mLogger.i("3002400" + orderID);
                                    } else { // 出货失败
                                        state = 4;
                                        String resTran = String.valueOf(result);
                                        //LGC出货失败流程分支 -1（应用与主控通信超时，发送50）; 01(出货检测失败，发送51);
                                        // 2（料道无货或故障，发送52）;3（主控接收驱动出货结果超时，发送故障至服务后台 53）
                                        mLogger.i("resTran:" + resTran);
                                        if ("-1".equals(resTran)) {
                                            socket = new Socket();
                                            socket.setSoTimeout(20000);
                                            address = new InetSocketAddress(mIp, mPort);
                                            socket.connect(address, 15000);
                                            socket.setKeepAlive(true);
                                            in = socket.getInputStream();
                                            out = socket.getOutputStream();
                                            out.write(encrypt("50", orderID).getBytes());
                                            out.flush();
                                        }
                                        String outGoodstate = resTran;
                                        mLogger.i("outGoodstate:" + outGoodstate);
                                        switch (outGoodstate) {
                                            case "1":
                                                out.write(encrypt("51", orderID).getBytes());
                                                out.flush();
                                                break;
                                            case "2":
                                                out.write(encrypt("52", orderID).getBytes());
                                                out.flush();
                                                break;
                                            case "3":
                                                out.write(encrypt("53", orderID).getBytes());
                                                out.flush();
                                                break;
                                            default:
                                                break;
                                        }
                                        //出货失败，发送失败广播
                                        sendResult(-1, tradeTrace, null);
                                        cleanup(0, "finish");
                                        return;
                                    }
                                }
                                break;
                            }
                        }
                        if (state == 3) {
                            out.write(encrypt("00", orderID).getBytes());
                            out.flush();
                            break;
                        }
                        if (state == 4) {
                            out.write(encrypt("50", orderID).getBytes());
                            out.flush();
                            break;
                        }
                    }
                } catch (IOException ioe) {
                    if (in != null)
                        in.close();
                    if (out != null)
                        out.close();
                    if (socket != null)
                        socket.close();
                    socket = new Socket();
                    socket.setSoTimeout(30000);
                    address = new InetSocketAddress(mIp, mPort);
                    socket.connect(address, 15000);
                    socket.setKeepAlive(true);
                    mLogger.e("IOException:" + ioe.getMessage());
                } catch (StringIndexOutOfBoundsException e) {
                    e.printStackTrace();
                    mLogger.e("StringIndexOutOfBoundsException:" + e.getMessage());
                }
                SystemClock.sleep(1000); // 睡眠1.5秒
                continue;
            }
            if (payState != 2 || isEmpty(buffer)) { // 循环结束时，byte数组为空，表示超时，发送超时信息给后台并返回
                mLogger.i("buffer is null");
                out.write(encrypt("04", orderID).getBytes());
                out.flush();
                cleanup(-2, "buffer is null");
                return;
            }
        } catch (IOException e) {
            mLogger.i("cause is : " + e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        cleanup(0, "finish");
    }

    private int getPayPrice(String orderID) {
        int price = 0;
        try {
            String payUrl = Configure.getConfigData(Configure.CONFIG_PAY_PRICE_URL);
            mLogger.i("payPriceUrl:" + payUrl);
            mLogger.i("orderID:" + orderID);
            if (payUrl == null || payUrl.length() == 0) {
                mLogger.e("payUrl为空:" + payUrl);
                return 0;
            }
            String encodeURL = URLEncoder.encode(orderID, "UTF-8");
            URL url = new URL(payUrl + encodeURL);
            HttpURLConnection connect = (HttpURLConnection) url.openConnection();
            connect.setRequestMethod("GET");
            connect.setConnectTimeout((int) TimeUnit.SECONDS.toMillis(5));
            connect.setReadTimeout((int) TimeUnit.SECONDS.toMillis(5));
            connect.setDoOutput(false);
            connect.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            InputStream inputStream = connect.getInputStream();
            byte[] bytes;
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            BufferedOutputStream bos = new BufferedOutputStream(baos);
            byte[] buffer = new byte[1024 * 8];
            int length;
            while ((length = bis.read(buffer)) > 0) {
                bos.write(buffer, 0, length);
            }
            bos.flush();
            bytes = baos.toByteArray();
            String result = new String(bytes, "utf-8");
            mLogger.i("payPriceUrl接口获取的的json串:" + result);
            //解析json值
            JSONObject object = new JSONObject(result);
            String code = object.getString("code");
            if ("0".equals(code)) {
                return object.getInt("amount");
            }

        } catch (Exception e) {
            mLogger.e("getPayPrice发生异常:" + e.toString());
            price = 0;
        } finally {

        }
        return price;
    }

    // 判断byte数组是否为空
    private boolean isEmpty(byte[] buffer) {
        for (int i = 0; i < buffer.length; i++) {
            if (buffer[i] != 0) {
                return false;
            }
        }
        return true;
    }

    private String encrypt(final String pParam, final String pOrder) {
        String encrypt = ETEncrypt.encode(pParam + pOrder);
        String message = "30" + Tools.addLeftZero(String.valueOf(encrypt.length()), 3) + encrypt;
        return message;
    }

    private void sendResult(final int pResult, final String pTrace, final String pType) {
//        Intent intent = new Intent(INTENT_OUT_GOODS);
//        intent.putExtra(EXTRA_OUT_GOODS_RESULT, pResult);
//        intent.putExtra(EXTRA_OUT_GOODS_TRACE, pTrace);
//        intent.putExtra(EXTRA_OUT_GOODS_TYPE, pType);
//        AppApplication.context.sendBroadcast(intent);
    }

    private void cleanup(final int pResultCode, final String pResultMessage) {
        TaskThreadPool.removeIdentifier(getIdentifier());
//        Intent intent = new Intent(INTENT_PICK_RESULT);
//        intent.putExtra(EXTRA_PICK_RESULT_CODE, pResultCode);
//        intent.putExtra(EXTRA_PICK_RESULT_MESSAGE, pResultMessage);
//        intent.putExtra(EXTRA_PICK_CODE, getIdentifier());
//        AppApplication.context.sendBroadcast(intent);
    }
}
